/**
 * -----------------------------------------------------------------
 * Copyright (c) 2012 hisoft, All Rights Reserved.
 * This software is the proprietary information of hisoft.
 * Use is subject to strict licensing terms.
 * -----------------------------------------------------------------
 *
 * @author: hisoft 2013-7-24   下午2:52:31
 * @brief: 类功能描述
 * @log: hisoft
 */

package com.evan.common.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class CommonDBUtility extends SQLiteOpenHelper {
	private static final String FIELDTYPE_TEXT = " text";

	public SQLiteDatabase db;

	public CommonDBUtility(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, factory, version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {

	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}

	public <T> ArrayList<T> query(Class<T> clazz) {
		ArrayList<T> list = new ArrayList<T>();
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		Cursor cursor = null;
		try {
			String table = null;
			/*if (clazz.getName().equals("com.smiier.skin.vo.TipMessageVo")) {

//				table = "CacheCommon";
				
				
				table = "TipMessageVo";

			} else {*/
				table = clazz.getSimpleName();
//			}
				
		   Log.i("testdb", "query.table:" + clazz.getSimpleName());

			cursor = db.query(table, null, null, null, null, null, null);

			while (cursor.moveToNext()) {
				list.add((T) Cursor2Object.parseDataSource(clazz, cursor));
			}
		} catch (Exception e) {
			// TODO: handle exception
			
			Log.i("testdb", "query.Exception:" + e.toString());
			e.printStackTrace();
		} finally {
			if (!CommonUtility.isNull(cursor)) {
				cursor.close();
			}
		}
		return list;
	}

	/**
	 * 
	 * @Title: query
	 * @Description: TODO
	 * @param @param tableName
	 * @param @param selection like "id=?,name=?"
	 * @param @param selectionArgs like new String[]{1, zhangsan}
	 * @param @param orderBy
	 * @param @return
	 * @param @throws BarsearchException
	 * @return List<?>
	 * @throws
	 */
	public <T> ArrayList<T> query(Class<T> clazz, String[] columns,
			String selection, String[] selectionArgs, String orderBy) {
		ArrayList<T> list = new ArrayList<T>();
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		Cursor cursor = null;
		try {
			cursor = db.query(clazz.getSimpleName(), columns, //selection
					null
					,
					//selectionArgs
					null
					, null, null, orderBy);
			while (cursor.moveToNext()) {
				list.add((T) Cursor2Object.parseDataSource(clazz, cursor));
			}
			
			
			Log.i("testchatdata", "db.list.size:" + list.size());
		} catch (Exception e) {
			Log.i("testchatdata", "db.exception:" + e.toString());
			e.printStackTrace();
		} finally {
			if (!CommonUtility.isNull(cursor)) {
				cursor.close();
			}
		}
		return list;
	}

	/**
	 * 
	 * @Title: query
	 * @Description: TODO
	 * @param @param tableName
	 * @param @param selection like "id=?,name=?"
	 * @param @param selectionArgs like new String[]{1, zhangsan}
	 * @param @param orderBy
	 * @param @return
	 * @param @throws BarsearchException
	 * @return List<?>
	 * @throws
	 */
	public <T> ArrayList<T> query(Class<?> clazz, String[] columns,
			String selection, String[] selectionArgs, String orderBy,
			Class<T> destClass) {
		ArrayList<T> list = new ArrayList<T>();
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		Cursor cursor = null;
		try {
			cursor = db.query(clazz.getSimpleName(), columns, selection,
					selectionArgs, null, null, orderBy);
			while (cursor.moveToNext()) {
				list.add((T) Cursor2Object.parseDataSource(destClass, cursor));
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (!CommonUtility.isNull(cursor)) {
				cursor.close();
			}
		}
		return list;
	}

	public JSONArray queryRJsonArray(Class<?> clazz) {
		return queryRJsonArray(clazz, null, null, null, null);
	}

	@SuppressWarnings({ "rawtypes" })
	public JSONArray queryRJsonArray(Class clazz, String[] columns,
			String selection, String[] selectionArgs, String orderBy) {
		JSONArray array = new JSONArray();
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		Cursor cursor = null;
		try {
			cursor = db.query(clazz.getSimpleName(), columns, selection,
					selectionArgs, null, null, orderBy);
			while (cursor.moveToNext()) {
				array.put(Cursor2Object
						.parseDataSourceJSONObject(clazz, cursor));
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			if (!CommonUtility.isNull(cursor)) {
				cursor.close();
			}
		}
		return array;
	}

	public void update(Class<?> clazz, ContentValues values,
			String whereClause, String[] whereArgs) {
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		try {
			delete(clazz, whereClause, whereArgs);
			insert(clazz, values);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}
	
	
	
	public void updata(String table,ContentValues values,String whereClause,String[] whereArgs){
		
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		
		
		db.update(table, values, whereClause, whereArgs);
		
	}
	
	
	
	
	
	

	/**
	 * @Title: getCount
	 * @Description: get count form given table by selectionArgs
	 * @param @param tableName
	 * @param @return
	 * @param @throws BarsearchException
	 * @return int
	 * @throws
	 */
	public int getCount(Class<?> clazz, String selection, String[] selectionArgs) {
		int count = 0;
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		Cursor cursor = null;
		try {
			StringBuilder sql = new StringBuilder("select count(*) from ");
			sql.append(clazz.getSimpleName());
			if (selection != null)
				sql.append(selection);
			cursor = db.rawQuery(sql.toString(), selectionArgs);

			if (null != cursor) {
				if (cursor.getCount() > 0) {
					cursor.moveToFirst();
					count = cursor.getInt(0);
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			release(null, cursor);
		}
		return count;
	}

	public void delete(Class<?> clazz, String whereClause, String[] whereArgs) {
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		try {
			db.delete(clazz.getSimpleName(), whereClause, whereArgs);

		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	public synchronized long insert(Class<?> clazz, ContentValues values) {
		if (CommonUtility.isNull(db)) {
			db = getReadableDatabase();
		}
		long id = db.insert(clazz.getSimpleName(), null, values);
		
		
		Log.i("testdre", "insert.id:" + id);
		return id;
	}

	public void release(SQLiteDatabase db, Cursor cursor) {
		if (!CommonUtility.isNull(cursor) && !cursor.isClosed()) {
			cursor.close();
		}
		if (!CommonUtility.isNull(db) && db.isOpen()) {
			db.close();
		}
	}

	public String generateSql(Class<?> clazz) {
		Field[] fields = clazz.getDeclaredFields();
		StringBuilder sb = new StringBuilder("create table ");
		sb.append(clazz.getSimpleName()).append(
				"(id integer primary key autoincrement, ");
		int length = fields.length;
		for (int i = 0; i < length; i++) {
			Field field = fields[i];
			String fieldName = field.getName();

			if (!fieldName.equals("serialVersionUID")) {
				sb.append(fieldName).append(FIELDTYPE_TEXT);
				if (i != length - 1) {
					sb.append(",");
				}
			}
		}
		sb.append(")");
		return sb.toString();
	}

	public ContentValues generateContentValues(Object object) {
		Field[] fields = object.getClass().getDeclaredFields();
		ContentValues values = new ContentValues();
		for (Field field : fields) {
			if (!field.getName().equals("serialVersionUID")) {
				Object o = null;
				try {
					o = field.get(object);
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				String value = "";
				if (!CommonUtility.isNull(o)) {
					value = o.toString();
				}
				values.put(field.getName(), value);
			}
		}
		return values;
	}

	public ContentValues generateContentValues(Class<?> clazz, JSONObject object) {
		Field[] fields = clazz.getDeclaredFields();
		ContentValues values = new ContentValues();
		for (Field field : fields) {
			String fieldName = field.getName();
			if (!field.getName().equals("serialVersionUID")) {
				String o = null;
				try {
					o = object.getString(fieldName);
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				String value = "";
				if (!CommonUtility.isNull(o)) {
					value = o.toString();
				}
				values.put(fieldName, value);
			}
		}
		return values;
	}

	/**
	 * 
	 * method desc： 保存数据到本地数据库
	 * 
	 * @param identity
	 *            自定义标识
	 * @param data
	 *            要保存的数据
	 * @param dataBindIdentity
	 *            区分角色的标识
	 * @param identityBak1
	 *            自定义标识预备字段
	 */
	public void saveOrUpdate(Object identity, Object data,
			Object dataBindIdentity, Object identityBak1) {
		try {
			ContentValues values = new ContentValues();
			values.put("data", data.toString());
			values.put("dataIdentity", identity.toString());
			values.put("dataBindIdentity", dataBindIdentity.toString());
			values.put("identityBak1", identityBak1.toString());
			update(CacheCommon.class,
					values,
					"dataIdentity=? and dataBindIdentity=? and identityBak1=?",
					new String[] { identity.toString(),
							dataBindIdentity.toString(),
							identityBak1.toString() });
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * method desc： 保存数据到本地数据库
	 * 
	 * @param identity
	 *            自定义标识
	 * @param data
	 *            要保存的数据
	 * @param dataBindIdentity
	 *            区分角色的标识
	 */
	public void saveOrUpdate(Object identity, Object data,
			Object dataBindIdentity) {
		try {
			ContentValues values = new ContentValues();
			values.put("data", data.toString());
			values.put("dataIdentity", identity.toString());
			values.put("dataBindIdentity", dataBindIdentity.toString());
			update(CacheCommon.class, values,
					"dataIdentity=? and dataBindIdentity=?", new String[] {
							identity.toString(), dataBindIdentity.toString() });
		} catch (Exception e) {
			// TODO: handle exception
			
			e.printStackTrace();
		}
	}

	private void getData(Object identity, Object dataBindIdentity) {
		
		ArrayList<CacheCommon> caches = query(CacheCommon.class, null,
				"dataIdentity=? and dataBindIdentity=?", new String[] {
						identity.toString(), dataBindIdentity.toString() },
				null);
	}

	/**
	 * 
	 * method desc：从本地数据库获取对应的数据
	 * 
	 * @param identity
	 *            自定义标识
	 * @param dataBindIdentity
	 *            区分角色的标识
	 * @return 返回指定的数据集
	 */
	public ArrayList<CacheCommon> queryCache(Object identity,
			Object dataBindIdentity) {
		return query(CacheCommon.class, null,
				"dataIdentity=? and dataBindIdentity=?", new String[] {
						identity.toString(), dataBindIdentity.toString() },
				null);
	}

	/**
	 * 
	 * method desc：从本地数据库获取对应的数据
	 * 
	 * @param identity
	 *            自定义标识
	 * @param dataBindIdentity
	 *            区分角色的标识
	 * @return 返回指定的数据集
	 */
	public ArrayList<CacheCommon> queryCache(Object identity,
			Object dataBindIdentity, Object identityBak1) {
		return query(CacheCommon.class, null,
				"dataIdentity=? and dataBindIdentity=? and identityBak1=?",
				new String[] { identity.toString(),
						dataBindIdentity.toString(), identityBak1.toString() },
				null);
	}

	/**
	 * 
	 * method desc： 保存数据到本地数据库
	 * 
	 * @param identity
	 *            自定义标识
	 * @param data
	 *            要保存的数据
	 * @param dataBindIdentity
	 *            区分角色的标识
	 */
	public void saveOrUpdate(Object identity, Object data) {
		try {
			ContentValues values = new ContentValues();
			values.put("data", data.toString());
			values.put("dataIdentity", identity.toString());
			update(CacheCommon.class, values, "dataIdentity=?",
					new String[] { identity.toString() });
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * method desc：从本地数据库获取对应的数据
	 * 
	 * @param identity
	 *            自定义标识
	 * @param dataBindIdentity
	 *            区分角色的标识
	 * @return 返回指定的数据集
	 */
	public ArrayList<CacheCommon> queryCache(Object identity) {
		return query(CacheCommon.class, null, "dataIdentity=? ",
				new String[] { identity.toString() }, null);
	}

}
